home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
change.cq
/
change.c
Wrap
Text File
|
1985-07-06
|
8KB
|
292 lines
/*
Change - text file line changer
last modified : 23 October 1983
usage: Change <from_string> <to_string> <filename> [<file2> <filen> -d -n -q -r]
Warning: generic filenames (* and ?) not implemented with CI-C86.
Change is a text search and replace program for multiple files. It
is useful for replacing text strings common to a batch of files,
for instance all the source files for a long program.
The command line file specifer(s) may be one or more ambiguous or
non-ambiguous file names.
For example:
Change from to foo <- chg operates on the file foo only
Change from to foo bar.* <- operates on the files foo, and any
expansions of bar.*
Change from to *.c?? <- chg operates on all files of type c
Change from to *.c* <- same as above
The command line dash options are:
-d(isplay) <- display all changes on the console
as they occur
-n(o line numbers) <- turns line numbering off (only
valid with -d option
-q(uery) <- prompt and ask before each change
-r(etain original) <- output (for each input file) goes to
the (created) file <infile.$$> (the
'$$' extention is added)
in default operation, the original
file is rename to type 'BAK' and
output goes to a newly created file
with the same name as the original
input file.
Copyright (c) 1983 by
Tony Rowe
3260 So. Penn
Englewood, Co. 80110
(303) 761-0755
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define ERROR (-1)
#define MAXLEN 300
#define bool char
#define INPUT "r"
#define OUTPUT "w"
#define DEFTYP ".$$"
#define BAKTYP ".BAK"
#define YES TRUE
#define NO FALSE
/* externals used mainly for the sake of speed */
FILE *InFile; /* disk file pointers */
FILE *OutFile;
char LineBuffer[2*MAXLEN]; /* line buffer */
char SearchPattern[MAXLEN]; /* search pattern buffer */
char ReplacementPattern[MAXLEN]; /* replace pattern string buffer */
char *Cp; /* general purpose character pointer */
int Line; /* line number */
bool ShowLineNumbers, ShowChanges, /* option flags */
AskBeforeChanging, RetainOriginalFile;
main(argc, argv)
int argc;
char *argv[];
{
char OutFName[MAXLEN]; /* output file name buffer */
char BackupFName[MAXLEN]; /* backup file name buffer */
char RestOfString[2*MAXLEN]; /* rest of string buffer */
short arg; /* argv index */
int ChangeFile(); /* routine to change strings */
"Copyright (c) 1983 by Tony Rowe";
ShowChanges = AskBeforeChanging = RetainOriginalFile = FALSE;
ShowLineNumbers = TRUE;
if (argc < 4) {
printf("%s\n%s\n",
"Usage: Change from_string to_string filename [filename...]",
"\t[-d(isplay) -n(o numbers) -q(uery) -r(etain original)]");
exit();
}
#ifdef CONSOLE
printf("\nSearch pattern: ");
fgets(SearchPattern, MAXLEN, stdin);
if (SearchPattern[0] == '\0')
exit();
printf("Replacement pattern: ");
fgets(ReplacementPattern, MAXLEN, stdin);
#else /* not CONSOLE */
strcpy(SearchPattern, argv[1]);
strcpy(ReplacementPattern, argv[2]);
if (! strcmp(ReplacementPattern, "\"\""))
strcpy(ReplacementPattern, "");
#endif /* def CONSOLE */
/* check args for options */
for (arg = 1; arg < argc; ++arg) {
if (argv[arg][0] == '-') {
switch (toupper(argv[arg][1])) {
case 'N':
ShowLineNumbers = FALSE;
continue;
case 'Q':
AskBeforeChanging = TRUE;
case 'D':
ShowChanges = TRUE;
continue;
case 'R':
RetainOriginalFile = TRUE;
continue;
default:
printf("\nBad option: %s\n", argv[arg]);
}
}
}
/* process filenames from command line, skipping '-' options */
for (arg = 3; arg < argc; ++arg) {
if (argv[arg][0] == '-') {
switch (toupper(argv[arg][1])) {
case 'D':
case 'N':
case 'Q':
case 'R':
continue;
} /* switch */
} /* if */
ProcessFiles(argv[arg], ChangeFile);
} /* for */
} /* main () */
ChangeFile (FileName)
char *FileName;
{
char OutFName[MAXLEN]; /* output file name buffer */
char BackupFName[MAXLEN]; /* backup file name buffer */
char RestOfString[2*MAXLEN]; /* rest of string buffer */
int PatternLength; /* length of replacement pattern */
bool FoundSearchPattern; /* save output file flag */
"Copyright (c) 1983 by Tony Rowe";
/* don't process any .COM files */
for (Cp = FileName; *Cp != '\0' && *Cp != '.'; ++Cp)
;
if (! strcmp(Cp, ".COM"))
return;
if ((InFile = fopen(FileName, INPUT)) == NULL) {
printf("\nNo file: %s\n", FileName);
return;
}
/* make output filenames */
strcpy(OutFName, FileName);
for (Cp = OutFName; *Cp != '\0' && *Cp != '.'; ++Cp)
;
*Cp = '\0';
strcpy(BackupFName, OutFName);
strcat(OutFName, DEFTYP);
strcat(BackupFName, BAKTYP);
if ((OutFile = fopen(OutFName, OUTPUT)) == NULL)
exit(printf("Can't create: %s\n", OutFName));
PatternLength = strlen(SearchPattern);
FoundSearchPattern = NO;
for (Line = 0; fgets(LineBuffer, MAXLEN, InFile); ++Line) {
for (Cp = LineBuffer; *Cp; ++Cp) {
if (strmatch(Cp, SearchPattern)) {
if ( (! FoundSearchPattern) && ShowChanges)
printf("\n%s\n", FileName);
FoundSearchPattern = YES;
if (ShowChanges) {
ShowLineNumbers?
printf("\n%05d: %s", Line, LineBuffer):
printf(LineBuffer);
if (AskBeforeChanging) {
putpointer(LineBuffer, Cp - LineBuffer,
ShowLineNumbers? 8: 0);
if (! askyn(" Change"))
continue;
}
}
strcpy(RestOfString, Cp + PatternLength);
strcpy(Cp, ReplacementPattern);
Cp += PatternLength + 1;
strcat(LineBuffer, RestOfString);
if (ShowChanges) {
ShowLineNumbers?
printf("%05d: %s", Line, LineBuffer):
printf(LineBuffer);
}
}
}
if (fputs(LineBuffer, OutFile) == ERROR) {
printf("Error writing a line to: %s\n", OutFName);
exit();
}
}
fclose(InFile);
if (FoundSearchPattern) {
if (fclose(OutFile) == ERROR) {
printf("Can't close: %s\n", OutFName);
exit();
}
if (RetainOriginalFile) {
unlink(BackupFName);
rename(FileName, BackupFName);
rename(OutFName, FileName);
}
else {
unlink(FileName);
rename(OutFName, FileName);
}
}
else {
fclose(OutFile);
unlink(OutFName);
}
} /* ChangeFile () */
strmatch(str, pat)
char *str, *pat;
{
while (*pat)
if (*str++ != *pat++)
return NO;
return YES;
}
askyn(prompt)
char *prompt;
{
while (TRUE) { /* forever */
printf(prompt);
printf(" ? ");
switch (GetInKey()) {
case 'y':
case 'Y':
printf("yes\t\t\n");
return YES;
case 'n':
case 'N':
printf("no\t\t\n");
return NO;
case '\3': /* control-C */
printf("^C");
exit();
default:
printf("\n(Y or N) \n");
}
}
}
/* put a string like " ^\n" on the console, left padded with spaces
* so that the '^' character is below string[index] on the screen.
* allow for tabs in the source string
*/
putpointer(string, index, offset)
char *string;
short index, offset;
{
short i;
while (offset--)
printf(" ");
for (i = 0; i < index; ++i)
printf(string[i] == '\t'? "\t": " ");
printf("^\n");
}
while (offset--)
printf(" ");
for (i =